package ejb.cbm.seguridad.session;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;

import ejb.cbm.commons.FormatoFecha;
import ejb.cbm.commons.JdbcHelper;
import ejb.cbm.seguridad.bean.RegistroIngresoBean;
import ejb.cbm.seguridad.bean.UsuarioBean;
import ejb.cbm.seguridad.entity.UsuarioEntity;
import ejb.cbm.seguridad.local.UsuarioSessionLocal;

////@Stateless
@Service("usuarioSessionLocal")
public class UsuarioSession  extends HibernateDaoSupport implements UsuarioSessionLocal {
	
	static Logger logger = Logger.getLogger(UsuarioSession.class.getName());
	
	//property constants
	public static final String CODIGOOFICINA = "codigooficina";
	public static final String NOMBRE = "nombre";
	public static final String APELLIDOPATERNO = "apellidopaterno";
	public static final String APELLIDOMATERNO = "apellidomaterno";
	public static final String TELEFONO = "telefono";
	public static final String CLAVE = "clave";
	public static final String CORREOELECTRONICO = "correoelectronico";
	public static final String FLAGLDAP = "flagldap";
	public static final String FLAGACTIVO = "flagactivo";
	public static final String USUARIOREGISTRO = "usuarioregistro";
	public static final String USUARIOMODIFICACION = "usuariomodificacion";
	
	@Autowired
	public UsuarioSession(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}


    //@PersistenceContext 
	//private EntityManager entityManager;
    public void save(UsuarioEntity transientInstance) {
    	logger.log("saving UsuarioEntity instance", Level.INFO, null,null);
        try {
            getSession().persist(transientInstance);
            logger.log("save successful", Level.INFO, null,null);
        } catch (RuntimeException re) {
        	logger.log("save failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    public void delete(UsuarioEntity persistentInstance) {
    	logger.log("deleting UsuarioEntity instance", Level.INFO, null,null);
        try {
            getSession().delete(persistentInstance);
            logger.log("delete successful", Level.INFO, null,null);
        } catch (RuntimeException re) {
        	logger.log("delete failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    public UsuarioEntity update(UsuarioEntity detachedInstance) {
    	logger.log("updating UsuarioEntity instance", Level.INFO, null,null);
        try {
            UsuarioEntity result = (UsuarioEntity) getSession().merge(detachedInstance);
            logger.log("update successful", Level.INFO, null,null);
            return result;
        } catch (RuntimeException re) {
            throw re;
        }
    }
    
    public UsuarioEntity findById( String id) {
    	logger.info("finding UsuarioEntity instance with id: " + id);
    	Session session1 = null;
        try {
        	session1 = getHibernateTemplate().getSessionFactory().openSession();
            UsuarioEntity instance = (UsuarioEntity) session1.get(UsuarioEntity.class, id);
            return instance;
        } catch (RuntimeException re) {
        	logger.fatal("find failed");
            throw re;
        }
    }
    
    //@SuppressWarnings("unchecked")
    public List<UsuarioEntity> findByProperty(String propertyName, Object value) {
    	logger.info("finding UsuarioEntity instance with property: " + propertyName
    						+ ", value: " + value);
		try {
			String queryString = "select model from UsuarioEntity model where model." 
			 						+ propertyName + "= :propertyValue";
			return getSession().createQuery(queryString)
 				.setParameter("propertyValue", value).list();
		} catch (RuntimeException re) {
			logger.fatal("find by property name failed");
			throw re;
		}
	}
	
	public List<UsuarioEntity> findByCodigooficina(Object codigooficina) {
		return findByProperty(CODIGOOFICINA, codigooficina);
	}
	
	public List<UsuarioEntity> findByNombre(Object nombre) {
		return findByProperty(NOMBRE, nombre);
	}
	
	public List<UsuarioEntity> findByApellidopaterno(Object apellidopaterno) {
		return findByProperty(APELLIDOPATERNO, apellidopaterno);
	}
	
	public List<UsuarioEntity> findByApellidomaterno(Object apellidomaterno) {
		return findByProperty(APELLIDOMATERNO, apellidomaterno);
	}
	
	public List<UsuarioEntity> findByTelefono(Object telefono) {
		return findByProperty(TELEFONO, telefono);
	}
	
	public List<UsuarioEntity> findByClave(Object clave) {
		return findByProperty(CLAVE, clave);
	}
	
	public List<UsuarioEntity> findByCorreoelectronico(Object correoelectronico) {
		return findByProperty(CORREOELECTRONICO, correoelectronico);
	}
	
	public List<UsuarioEntity> findByFlagldap(Object flagldap) {
		return findByProperty(FLAGLDAP, flagldap);
	}
	
	public List<UsuarioEntity> findByFlagactivo(Object flagactivo) {
		return findByProperty(FLAGACTIVO, flagactivo);
	}
	
	public List<UsuarioEntity> findByUsuarioregistro(Object usuarioregistro) {
		return findByProperty(USUARIOREGISTRO, usuarioregistro);
	}
	
	public List<UsuarioEntity> findByUsuariomodificacion(Object usuariomodificacion) {
		return findByProperty(USUARIOMODIFICACION, usuariomodificacion);
	}
	

	//@SuppressWarnings("unchecked")
	public List<UsuarioEntity> findAll() {
		logger.info("finding all UsuarioEntity instances");
		try {
			String queryString = "select model from UsuarioEntity model";
			return getSession().createQuery(queryString).list();
		} catch (RuntimeException re) {
			logger.fatal("find all failed");
			throw re;
		}
	}
	
	//@SuppressWarnings("unchecked")
	public List<UsuarioEntity> findByFiltro(UsuarioBean filtro){
		logger.info("UsuarioSession.findByFiltro UsuarioEntity instance");
		StringBuilder query = new StringBuilder();
		
		try{
			query.append("select a ");
			query.append("from UsuarioEntity model");
			query.append("where 1=1");
			
			if(filtro.getCodigousuario() != null){
				query.append(" and model.codigousuario = "+filtro.getCodigousuario());
			}
			if(filtro.getApellidopaterno() != null){
				query.append(" and model.apellidopaterno = "+filtro.getApellidopaterno());
			}
			if(filtro.getApellidomaterno()!= null){
				query.append(" and model.apellidomaterno = "+filtro.getApellidomaterno());
			}
			if(filtro.getNombre() != null){
				query.append(" and model.nombre = "+filtro.getNombre());
			}
			/*if(usuarioBean.getCodigoPuesto() != null){
				query.append("model.nombreUsuario = "+usuarioBean.getNombreUsuario());
			}*/
			if(filtro.getFlagactivo()!= null){
				query.append(" and model.flagactivo = "+filtro.getFlagactivo());
			}
			if(filtro.getTelefono()!= null){
				query.append(" and model.telefono = "+filtro.getTelefono());
			}
			if(filtro.getCorreoelectronico()!= null){
				query.append(" and model.correoelectronico = "+filtro.getCorreoelectronico());
			}

			return getSession().createQuery(query.toString()).list();
		
		}catch(RuntimeException e){
			logger.fatal("UsuarioSession.findByFiltro failed");
			throw e;
		}
	}
	
	//@SuppressWarnings("unchecked")
	public List<UsuarioBean> findUsuarios(Connection con, 
										  UsuarioBean filtro,
										  RegistroIngresoBean registroIngreso
										  ) throws SQLException{
		
		logger.info("findByFiltro UsuarioEntity instance");
		List<UsuarioBean> lstResultado = new ArrayList<UsuarioBean> ();
		
		try{
			
			CallableStatement cs = null;
			UsuarioBean bean = null;
			ResultSet rs = null;
			
			try{
				cs = con.prepareCall("call CONNEG.PQ_CONTINUIDAD.sp_obtener_usuario_perfil(?,?,?,?,?,?,?,?,?,?,?,?,?)");
				cs.setString(1,registroIngreso.getCodigousuario());
				cs.setString(2,registroIngreso.getUsuarioBean().getPerfilBean().getTipoperfil()+"");
				cs.setString(3,registroIngreso.getCodigooficina()+"");
				cs.setString(4,filtro.getCodigousuario());
				cs.setString(5,filtro.getCodigooficina());
				cs.setString(6,filtro.getNombre());
				cs.setString(7,filtro.getApellidopaterno());
				cs.setString(8,filtro.getApellidomaterno());
				cs.setString(9,filtro.getTelefono());
				cs.setString(10,filtro.getCodigoPuesto());
				cs.setString(11,JdbcHelper.to_char(filtro.getFlagactivo()));
				cs.setString(12,FormatoFecha.dateUtilToStringDDMMYYYY(filtro.getFecharegistro()));
				cs.registerOutParameter(13,OracleTypes.CURSOR);
				cs.executeQuery();
				rs = (ResultSet)cs.getObject(13);
				
				while(rs.next()){
					bean = new UsuarioBean();
					bean.setCodigousuario(rs.getString("CODIGOUSUARIO"));
					bean.setCodigooficina(rs.getString("CODIGOOFICINA"));
					bean.setNombre(rs.getString("NOMBRE"));
					bean.setApellidopaterno(rs.getString("APELLIDOPATERNO"));
					bean.setApellidomaterno(rs.getString("APELLIDOMATERNO"));
					bean.setTelefono(rs.getString("TELEFONO"));
					bean.setCorreoelectronico(rs.getString("CORREOELECTRONICO"));
					bean.setFlagldap(rs.getLong("FLAGLDAP"));
					bean.setCodigoPuesto(rs.getString("CODIGOPUESTO"));
					bean.setFlagactivo(rs.getLong("FLAGACTIVO"));
					lstResultado.add(bean);
				}
				
			}catch (Exception e) {
				e.printStackTrace();logger.error(e);
			}
			finally{
				JdbcHelper.close(null,cs,null,null,rs);
			}
			
			return lstResultado;
			
		}catch(RuntimeException e){
			logger.fatal("findUsuariosByPerfil failed");
			throw e;
		}
	}
}